/**
  ******************************************************************************
  * File Name          : measure.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention : 注意单位!!! 
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "measure.h"
#include "parameter.h"
#include <stdlib.h>
#include "gui.h"

double sw_flowrate_theory_0d1g_0d01s = 0.0;

static inline void meas_calsw_init(GlobalVariablesStru *pgv)
{
  sw_flowrate_theory_0d1g_0d01s = 0.0;
  
  pgv->ir.meas_ca.calsw_elapsed_belt_cnt = 0;
  pgv->ir.meas_ca.calsw_wtfactor_adjust = 0;
  pgv->ir.meas_ca.calsw_wtfactor_correct = 0;
  pgv->ir.meas_ca.calsw_belt_remainder_mm = 0;
  pgv->ir.meas_ca.calsw_belt_remainder_0d01s = 0;
  pgv->ir.meas_ca.calsw_elapsed_time_0d01s = 0;
  pgv->ir.meas_ca.calsw_elapsed_pulse = 0;
  pgv->ir.meas_ca.calsw_actual_total_0d1g = 0;
//  pgv->ir.meas_ca.calsw_theory_total_0d1g = 0;

  pgv->ir.meas_ca.calibrate_timeout = 0;
  
  pgv->co.meas_ec.cal_shiwu_save_seg_key = 0;
  pgv->co.meas_ec.cal_shiwu_save_all_key = 0;

  pgv->di.meas_is.calsw_msg = 0;
}

static inline Meas_ReturnEnum meas_calsw_process(double flowrate_0d1g_0d01s, GlobalVariablesStru *pgv)
{
  float ppl_0d1mm; /* 单位长度的脉冲数 */
  float belt_elapsed_len_0d1mm;
  double double_wtfactor_adjust;
  uint64_t belt_len_pulse;
  
  pgv->ir.meas_ca.calsw_elapsed_time_0d01s++;                    /* 流逝的时间,以0.01s为单位 */
  pgv->ir.meas_ca.calsw_elapsed_pulse += pgv->ir.meas_ad.sad_100hz;  /* 累加速度脉冲数 */
  pgv->ir.meas_ca.calsw_actual_total_0d1g += flowrate_0d1g_0d01s;

  if(pgv->hr.meas_pa.cal_shiwu_wtacc == MEAS_SHIWU_WTACC_YES)            /* 判别实物校验物料是否计入产量 */
  {
    meas_accrue(flowrate_0d1g_0d01s, pgv);
  }
  
  if(pgv->hr.meas_pa.len_circle_mode == MEAS_LEN_CIRCLE_FIXLENG)
  {
    /* 定长模式下,当皮带运行过的长度等于皮带周长后,判别物料是否过完 */
    /* 转小单位来保证精度不丢失(或用浮点算),否则皮带越长,丢失的精度越多 */
    ppl_0d1mm = (float)pgv->hr.meas_pa.speed_wheel_pls / (float)pgv->hr.meas_pa.speed_wheel_cir_0d1mm;    /* 计算单位长度(0.1mm)的脉冲数 */
    belt_len_pulse = ((float)pgv->hr.meas_pa.belt_length_mm * 10.0) * ppl_0d1mm;                      /* 计算皮带整长所需脉冲数 */
    
    belt_elapsed_len_0d1mm = (float)pgv->ir.meas_ca.calsw_elapsed_pulse / ppl_0d1mm;              /* 计算皮带转过的长度 */
    pgv->ir.meas_ca.calsw_belt_remainder_mm = pgv->hr.meas_pa.belt_length_mm - (belt_elapsed_len_0d1mm / 10.0); /* 计算皮带剩余的长度 */

    if(pgv->ir.meas_ca.calsw_elapsed_pulse >= belt_len_pulse)
    {
      pgv->ir.meas_ca.calsw_elapsed_belt_cnt++;
      pgv->ir.meas_ca.calsw_elapsed_pulse = 0;
      
      if(pgv->co.meas_ec.cal_shiwu_passed_key == 1)
      {
        pgv->co.meas_ec.cal_shiwu_passed_key = 0;
        
        /* 物料过完后,切换仪表进入实物校验完成状态 */
        if(pgv->ir.meas_ca.calsw_actual_total_0d1g <= 0)
        {
          return RET_FAIL; /* 挂码校验失败 */
        }
        
        sw_flowrate_theory_0d1g_0d01s = (pgv->hr.meas_pa.cal_shiwu_weight_kg*10000) / pgv->ir.meas_ca.calsw_elapsed_time_0d01s; /* 计算理论流量 */
        
        double_wtfactor_adjust = 10000.0;
        double_wtfactor_adjust *= (double)pgv->hr.meas_pa.weight_factor_base;
        double_wtfactor_adjust *= (double)pgv->hr.meas_pa.cal_shiwu_weight_kg;
        double_wtfactor_adjust /= (double)pgv->ir.meas_ca.calsw_actual_total_0d1g;
        
        pgv->ir.meas_ca.calsw_wtfactor_adjust = double_wtfactor_adjust;
        if((double_wtfactor_adjust - pgv->ir.meas_ca.calsw_wtfactor_adjust) >= 0.5)
        {
          pgv->ir.meas_ca.calsw_wtfactor_adjust++;
        }
        
        if(pgv->ir.meas_ca.calsw_wtfactor_adjust == 0)
        {
          return RET_FAIL; /* 实物校验失败 */
        }

        return RET_SUCCESS; /* 实物校验成功 */
      }
    }
  }
  else
  {
    /* 定时模式下,当皮带运行过的时间等于皮带周期后,判别物料是否过完 */
    pgv->ir.meas_ca.calsw_belt_remainder_0d01s = pgv->hr.meas_pa.belt_period_0d01s - pgv->ir.meas_ca.calsw_elapsed_time_0d01s;
    
    if(pgv->ir.meas_ca.calsw_elapsed_time_0d01s >= pgv->hr.meas_pa.belt_period_0d01s)
    {
      pgv->ir.meas_ca.calsw_elapsed_belt_cnt++;
      pgv->ir.meas_ca.calsw_elapsed_time_0d01s = 0;
      
      if(pgv->co.meas_ec.cal_shiwu_passed_key == 1)
      {
        pgv->co.meas_ec.cal_shiwu_passed_key = 0;
        
        /* 物料过完后,切换仪表进入实物校验完成状态 */
        if(pgv->ir.meas_ca.calsw_actual_total_0d1g <= 0)
        {
          return RET_FAIL; /* 挂码校验失败 */
        }
        
        sw_flowrate_theory_0d1g_0d01s = (pgv->hr.meas_pa.cal_shiwu_weight_kg*10000) / pgv->ir.meas_ca.calsw_elapsed_time_0d01s; /* 计算理论流量 */
        
        double_wtfactor_adjust = 10000.0;
        double_wtfactor_adjust *= (double)pgv->hr.meas_pa.weight_factor_base;
        double_wtfactor_adjust *= (double)pgv->hr.meas_pa.cal_shiwu_weight_kg;
        double_wtfactor_adjust /= (double)pgv->ir.meas_ca.calsw_actual_total_0d1g;
        
        pgv->ir.meas_ca.calsw_wtfactor_adjust = double_wtfactor_adjust;
        if((double_wtfactor_adjust - pgv->ir.meas_ca.calsw_wtfactor_adjust) >= 0.5)
        {
          pgv->ir.meas_ca.calsw_wtfactor_adjust++;
        }
        
        if(pgv->ir.meas_ca.calsw_wtfactor_adjust == 0)
        {
          return RET_FAIL;  /* 挂码校验失败 */
        }

        return RET_SUCCESS; /* 挂码校验成功 */
      }
    }
  }
  
  return RET_RUNNING;
}

static Meas_ReturnEnum meas_calsw_waitsave(GlobalVariablesStru *pgv)
{    
  if(pgv->co.meas_ec.cal_shiwu_save_seg_key == 1) /* 修正标定 */
  {
    pgv->co.meas_ec.cal_shiwu_save_seg_key = 0;
    
    pgv->ir.meas_ca.calsw_wtfactor_correct = pgv->ir.meas_ca.calsw_wtfactor_adjust - pgv->hr.meas_pa.weight_factor_base;  /* 计算修正值 */

    if(sw_flowrate_theory_0d1g_0d01s <= (400.0/F_MUL_0D1G_0D01S_TO_TH))
    {
      sto_update_item(sto_mtidx(weight_factor05), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_correct, 5);
    }
    else if((sw_flowrate_theory_0d1g_0d01s > (400.0/F_MUL_0D1G_0D01S_TO_TH)) && (sw_flowrate_theory_0d1g_0d01s <= (800.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor04), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_correct, 5);
    }
    else if((sw_flowrate_theory_0d1g_0d01s > (800.0/F_MUL_0D1G_0D01S_TO_TH)) && (sw_flowrate_theory_0d1g_0d01s <= (1200.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor03), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_correct, 5);
    }
    else if((sw_flowrate_theory_0d1g_0d01s > (1200.0/F_MUL_0D1G_0D01S_TO_TH)) && (sw_flowrate_theory_0d1g_0d01s <= (1600.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor02), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_correct, 5);
    }
    else if(sw_flowrate_theory_0d1g_0d01s > (1600.0/F_MUL_0D1G_0D01S_TO_TH))
    {
      sto_update_item(sto_mtidx(weight_factor01), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_correct, 5);
    }
    
    pgv->ir.meas_ca.calibrate_timeout = 0;
    
    return RET_SUCCESS;
  }
  
  if(pgv->co.meas_ec.cal_shiwu_save_all_key == 1) /* 基础标定 */
  {
    pgv->co.meas_ec.cal_shiwu_save_all_key = 0;

    sto_update_item(sto_mtidx(weight_factor_base), (const Sto_CellUnion *)&pgv->ir.meas_ca.calsw_wtfactor_adjust, 5);

    pgv->ir.meas_ca.calibrate_timeout = 0;

    return RET_SUCCESS;
  }

  if(pgv->ir.meas_ca.calibrate_timeout++ >= MEAS_CALIBRATE_WATI_SAVE_TIMEOUT)
  {
    return RET_FAIL;
  }

  return RET_RUNNING;
}

static inline void meas_calsw_exit(GlobalVariablesStru *pgv)
{
  pgv->ir.meas_ca.calibrate_timeout = 0;
}

Meas_ReturnEnum meas_calibrate_shiwu(double flowrate_0d1g_0d01s, GlobalVariablesStru *pgv)
{
  uint8_t res;
  Meas_ReturnEnum ret;
  Gui_CmdQueStru scmd;

  ret = RET_RUNNING;

  if(pgv->co.meas_ec.cal_shiwu_stop_key == 1)
  {
    pgv->co.meas_ec.cal_shiwu_stop_key = 0;
    pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_SENDMSG;
    pgv->di.meas_is.calsw_msg = 1;
  }

  switch(pgv->ir.meas_ca.calsw_substmachine)
  {
    case CALSW_SUB_STATE_MACHINE_INIT:
      meas_calsw_init(pgv);
      pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_PROCESS;

    case CALSW_SUB_STATE_MACHINE_PROCESS:
      res = meas_calsw_process(flowrate_0d1g_0d01s, pgv);
      if(res == RET_SUCCESS)
      {
        pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_WAITSAVE;
        xQueueSend(gui_cmd_qhd, &gui_cmd_go_calswend, 2);   /* 切换校验完成页面 */
      }
      else if(res == RET_FAIL)
      {
        pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calsw_msg = 2;
        break;
      }
      else
      {
        break; /* go on */
      }

    case CALSW_SUB_STATE_MACHINE_WAITSAVE:
      res = meas_calsw_waitsave(pgv);
      if(res == RET_SUCCESS)
      {
        pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calsw_msg = 3;
      }
      else if(res == RET_FAIL)
      {
        pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calsw_msg = 4;
      }
      else
      {
        break; /* go on */
      }

    case CALSW_SUB_STATE_MACHINE_SENDMSG:
      pgv->ir.meas_ca.calsw_substmachine = CALSW_SUB_STATE_MACHINE_EXIT;
      scmd.cmd = GUI_CMD_CHANGE_FORM;
      scmd.key = IRKEY_KEY_VALUE_NULL;
      scmd.toform = &gui_from_calmessage;
      scmd.msg = pgv->di.meas_is.calsw_msg;
      xQueueSend(gui_cmd_qhd, &scmd, 2);

    default:
    case CALSW_SUB_STATE_MACHINE_EXIT:
      meas_calsw_exit(pgv);
      return RET_EXIT;
  }

  return ret;
}

